//
// Created by 31897 on 2021/11/2.
//

#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h>
#include <string.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <time.h>

//                        0    1    2    3    4    5    6    7    8    9    -   off
unsigned char tube[] = { 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x7f,0xff };

unsigned char addr[] = { 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 };

int time_state = 0;

int isLegal(char* clock) {
    //小时超过29
    if (clock[0] > '2' || clock[0] < '0') {
        return 0;
    }
    //小时数在24-29
    if (clock[0] == '2' && clock[1] > '3') {
        return 0;
    }
    //第2位不在0-9之间
    if (clock[1] < '0' || clock[1]>'9') {
        return 0;
    }
    //第5位不在0-9之间
    if (clock[4] < '0' || clock[4]>'9') {
        return 0;
    }
    //第8位不在0-9之间
    if (clock[7] < '0' || clock[7]>'9') {
        return 0;
    }
    //第3位和第6位不是冒号
    if (clock[2] != ':' || clock[5] != ':') {
        return 0;
    }
    //分数超过59
    if (clock[3] > '5' || clock[3] < '0') {
        return 0;
    }
    //秒数超过59
    if (clock[6] > '5' || clock[6] < '0') {
        return 0;
    }
    return 1;
}

void* time_moving(char* clock) {
    clock_t start, finish;
    while (1) {
        while (time_state == 1) {
            if (clock[7] != '9') {
                clock[7]++;
            }
            else {//秒进位
                clock[7] = '0';
                if (clock[6] != '5') {
                    clock[6]++;
                }
                else {//分加一
                    clock[6] = '0';
                    if (clock[4] != '9') {
                        clock[4]++;
                    }
                    else {//分进位
                        clock[4] = '0';
                        if (clock[3] != '5') {
                            clock[3]++;
                        }
                        else {
                            clock[3] = '0';
                            //时加一
                            if (clock[0] != '2' && clock[1] != '9') {
                                clock[1]++;
                            }
                            else if (clock[0] == '2' && clock[1] != '3') {
                                clock[1]++;
                            }
                            else if (clock[0] != '2' && clock[1] == '9') {//时进位
                                clock[1] = '0';
                                clock[0]++;
                            }
                            else {//下一天
                                clock[1] = clock[0] = '0';
                            }
                        }
                    }
                }
            }
            usleep(990000);
        }
        while (time_state == 0);
    }
}

int main(int argc, char* argv[]) {
    int i = 0, j = 0;
    int mem_fd;
    char time[8];
    unsigned char* cpld;
    pthread_t th_time;
    void* retval;
    strcpy(time, argv[1]);
    // mem_fd = open("/dev/mem", O_RDWR);

    // cpld = (unsigned char*)mmap(NULL,(size_t)0x10,PROT_READ | PROT_WRITE | PROT_EXEC,MAP_SHARED,mem_fd,(off_t)(0x8000000));

    // if(cpld == MAP_FAILED)
    //    return;

    // 参数判断是否合法
    if (!isLegal(time)) {
        printf("input error!");
        return 0;
    }
    pthread_create(&th_time, NULL, time_moving, 0);
    while (1) {
        i = 0;
        int k;
        //start = clock();

        switch (i) {
        case 0:
            printf("%c", time[0]);
            // printf("%c", time[i]);
            // *(cpld+(0xe6<<1)) = addr[i];   //数码管地址  (0xe6<<1)为地址
            // *(cpld+(0xe4<<1)) = tube[time[i]='0'];
            break;

        case 1:
            printf("%c", time[1]);
            // printf(" %c", time[i]);
            // *(cpld+(0xe6<<1)) = addr[i];   //数码管地址
            // *(cpld+(0xe4<<1)) = tube[time[i]='0'];
            break;

        case 2:
            printf("%c", time[2]);
            // printf("  %c", time[i]);
            // *(cpld+(0xe6<<1)) = addr[i];   //数码管地址
            // *(cpld+(0xe4<<1)) = tube[10];
            break;

        case 3:
            printf("%c", time[3]);
            // printf("   %c", time[i]);
            // *(cpld+(0xe6<<1)) = addr[i];   //数码管地址
            // *(cpld+(0xe4<<1)) = tube[time[i]='0'];
            break;

        case 4:
            printf("%c", time[4]);
            // printf("    %c", time[i]);
            // *(cpld+(0xe6<<1)) = addr[i];   //数码管地址  (0xe6<<1)为地址
            // *(cpld+(0xe4<<1)) = tube[time[i]='0'];
            break;

        case 5:
            printf("%c", time[5]);
            // printf("     %c", time[i]);
            // *(cpld+(0xe6<<1)) = addr[i];   //数码管地址
            // *(cpld+(0xe4<<1)) = tube[10];
            break;

        case 6:
            printf("%c", time[6]);
            // printf("      %c", time[i]);
            // *(cpld+(0xe6<<1)) = addr[i];   //数码管地址
            // *(cpld+(0xe4<<1)) = tube[time[i]='0'];
            break;

        case 7:
            printf("%c", time[7]);
            // printf("       %c", time[i]);
            // *(cpld+(0xe6<<1)) = addr[i];   //数码管地址
            // *(cpld+(0xe4<<1)) = tube[time[i]='0'];
            break;

        default:
            break;
        }
        time_state = 1;
        //延时显示各个数字
        usleep(1000);
        ++i;
        if (i == 8) {
            for (k = 0;k <= i;k++) {
                printf("\b");
            }
            i = 0;
        }

        //finish = clock();
        //usleep(1000000-finish+start);  
    }
    pthread_join(th_time, &retval);
    // munmap(cpld,0x10);

    // close(mem_fd);

    return 0;
}
